home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
ddj9304.zip
/
DIFFCOMP.ZIP
/
PACK.C
< prev
next >
Wrap
Text File
|
1992-11-24
|
4KB
|
133 lines
/****************************************************************************/
/* PACK.C */
/* By James Sylvester -- From DDJ for February 1993 -- Last Updated 9/22/92 */
/****************************************************************************/
#include <stdio.h>
void main(int argc, char *argv[])
{
const blockfactor = 1; /* adjust as desired */
const blocksize = blockfactor * 8;
char buffer [257] [8]; /* enter blocksize for second index */
int i, j, currentsize;
FILE *sf, *tf; /* sourcefile & targetfile respectively */
int bestblock; /* best matching block in buffer */
int bestcount, matchcount;
int changeindex, bitvalue;
/* Verify and perform error handling for opening both the input file and */
/* the output file as binary files. Note, the input file has the original */
/* data and the output file will contain the encoded/compressed data. */
if (argc != 3)
{
printf("Correct usage is >pack source_filename target_filename\n");
exit(1);
}
if ((sf = fopen(argv[1], "rb"))==NULL) /* read only mode for input file */
{
printf("Unable to open source file %s\n", argv[1]);
exit(2);
}
if ((tf = fopen(argv[2], "wb"))==NULL) /* write only mode for output file */
{
printf("Unable to open target file %s\n", argv[2]);
exit(3);
}
/* Initialize buffer with all zeros in the first block, all ones in the */
/* second block, and so forth so that there will be at least one matching */
/* byte in the first block of input data regardless what it might be. */
for (i = 0; i < 256; i++)
for (j = 0; j < blocksize; j++)
buffer [i] [j] = i;
while (1) /* while true ==> stay in loop until internal exit */
{
/* Load the next block of data from the sourcefile into the last slot of */
/* the buffer. Also, keep track of how many bytes were read to signify */
/* proper handling for the unfull block when at the end of file. */
currentsize = blocksize;
for (j = 0; j < blocksize; j++)
{
i = getc(sf);
if (i == EOF)
{
currentsize = j; /* reset correct currentsize */
break; /* exit for loop */
}
buffer [256] [j] = i; /* put character into last block */
}
if (currentsize == 0) /* input data ended with previous full block */
{
printf("%s now contains encoded/compressed data!\n", argv[2]);
exit(4);
}
/* Find the best matching block in buffer for the recently loaded block */
/* of input data. Afterwards, send the bestblock index to the output */
/* file and process the changes between the two blocks. */
bestcount = -1;
for (i = 0; i < 256; i++)
{
matchcount = 0;
for (j = 0; j < currentsize; j++)
if (buffer [i] [j] == buffer [256] [j])
matchcount++;
if (matchcount > bestcount)
{
bestcount = matchcount;
bestblock = i;
if (bestcount == currentsize)
break; /* exit for loop */
}
}
putc (bestblock, tf);
for (i = 0; i < blockfactor; i++)
{
changeindex = 0;
bitvalue = 1;
for (j = i*8; j < i*8+8; j++)
{
if (j >= currentsize)
break;
if (buffer [bestblock] [j] != buffer [256] [j])
changeindex += bitvalue;
bitvalue *= 2;
}
putc(changeindex, tf);
for (j = i*8; j < i*8+8; j++)
{
if (changeindex % 2 == 1)
putc(buffer [256] [j], tf);
changeindex /= 2;
}
}
if (currentsize < blocksize) /* input data ended with unfull block */
{
putc(currentsize, tf);
printf("%s now contains encoded/compressed data!\n", argv[2]);
exit(5);
}
/* Update the best matching block in buffer with new data. */
/* Compression should now improve as further loaded blocks */
/* closely match the exact copies kept in the buffer. */
for (j = 0; j < blocksize; j++)
buffer [bestblock] [j] = buffer [256] [j];
}
}